﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using ServerFramework.Tools;

namespace ServerFramework.ORM
{
    /// <summary>
    /// 数据库列
    /// </summary>
    public class DbColum
    {

        public static DbColum CreateDbColum(PropertyInfo info)
        {
            DbDataAttribute attr = Attribute.GetCustomAttribute(info,typeof(DbDataAttribute)) as DbDataAttribute;
            if(attr != null)
            {
                DbColum col = new DbColum();
                col.IsKey = attr.IsKey;
                col.IsIdentity = attr.IsIdentity;
                col.Isnullable = attr.Isnullable;
                col.Length = attr.Length;
                col.Name = info.Name;
                col.Type = info.PropertyType;
                col.Scale = attr.Scale;
                return col;
            }
            return null;
        }

        public static string CreateColumSql(DbColum col)
        {
            StringBuilder sql = new StringBuilder();
            sql.AppendFormat("{0} {1} {2} {3} ",
                                      FormatName(col.Name),
                                     ConvertToDbType(col.Type, col.Length, col.Scale, col.IsKey, col.Name),
                                     col.Isnullable ? "" : " NOT NULL",
                                     (col.IsIdentity ? " AUTO_INCREMENT" : ""));
            if(col.IsKey)
            {
                sql.Append("PRIMARY KEY");
            }

            return sql.ToString();
        }

        public static string ConvertToDbType(Type type, long length, int scale, bool isKey, string fieldName)
        {
            if (type.Equals(typeof(Int64)) || type.Equals(typeof(UInt64)))
            {
                return "BigInt";
            }
            if (type.Equals(typeof(Boolean)))
            {
                return "Bit";
            }
            if (type.Equals(typeof(DateTime)))
            {
                return "DateTime";
            }
            if (type.Equals(typeof(Decimal)))
            {
                return "Decimal(18, " + (scale == 0 ? 4 : scale) + ")";
            }
            if (type.Equals(typeof(Double)))
            {
                return "Float";
            }
            if (type.IsEnum || type.Equals(typeof(Int32)) || type.Equals(typeof(UInt32)))
            {
                return "Int";
            }
            if (type.Equals(typeof(Single)))
            {
                return "Real";
            }
            if (type.Equals(typeof(Int16)) || type.Equals(typeof(UInt16)))
            {
                return "SmallInt";
            }
            if (type.Equals(typeof(Byte)))
            {
                return "TinyInt";
            }
            if (type.Equals(typeof(Byte[])))
            {
                return "LongBlob";
            }

            if (type.Equals(typeof(Guid)))
            {
                return "VarChar(32)";
            }
            if (type.Equals(typeof(String)))
            {
                if (isKey && length == 0)
                {
                    return "VarChar(100)";
                }
                return length > 0
                    ? length >= 4000 ? "longtext" : "VarChar(" + length + ")"
                    : "VarChar(255)";
            }
            else
            {
                if (length == 0)
                {
                    return "VarChar(100)";
                }
                return length > 0
                    ? length >= 4000 ? "longtext" : "VarChar(" + length + ")"
                    : "VarChar(255)";
            }
        }
        public static string FormatName(string name)
        {
            if (name.StartsWith("`") || name.IndexOf("(") != -1)
            {
                return name;
            }
            return string.Format("`{0}`", name);
        }

        public static List<DbColum> CreateDbColums(Type tableType)
        {
            List<DbColum> cols = new List<DbColum>();
            PropertyInfo[] props = tableType.GetProperties();
            foreach (PropertyInfo p in props)
            {
                DbColum col = CreateDbColum(p);
                if(col != null)
                {
                    cols.Add(col);
                }
            }
            var temp = cols[cols.Count - 1];
            cols.RemoveAt(cols.Count - 1);
            cols.Insert(0, temp);
            return cols;
        }
     
        /// 是否是主键
        /// </summary>
        public bool IsKey { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 类型
        /// </summary>
        public Type Type { get; set; }
        /// <summary>
        /// 长度
        /// </summary>
        public long Length { get; set; }
        /// <summary>
        /// decimal类型指精度范围
        /// </summary>
        public int Scale { get; set; }
        /// <summary>
        /// 是否可为空
        /// </summary>
        public bool Isnullable { get; set; }

        /// <summary>
        /// 是否是自增列
        /// </summary>
        /// <value><c>true</c> if this instance is identity; otherwise, <c>false</c>.</value>
        public bool IsIdentity { get; set; }

      
    }
}
